-- 游戏中的实体对象基类

-- 模块定义
local M = 
{
    _base_class = require "objects.Object",
    _class_name = "objects.GameEntity"
};
setmetatable (M, {__index = _G; });
_ENV = M;

-- 引用模块
local Tools = require "tools.CommonTools";
local Map_safe_iter = require "collections.MapSafeIter";

-- 方法定义
operation_table = Tools.CreateOperationTable (_base_class);

-- 获取id
function operation_table.GetId (self)
    return self._id;
end;

-- 设置名称
function operation_table.SetName (self, new_name)
    self._name = new_name;
end;

-- 获取名称
function operation_table.GetName (self)
    return self._name;
end;

-- 添加组件
function operation_table.AddComponent (self, comp_class)
    local class_name = Tools.GetClassName (comp_class);
    local comp_instance = comp_class["New" .. class_name] ();
    self._components:Add (class_name, comp_instance);
    comp_instance:OnAddedToHost (self);
    return comp_instance;
end;

-- 删除组件
function operation_table.RmvComponent (self, comp_class)
    local class_name = Tools.GetClassName (comp_class);
    if (self._components:ContainsKey (class_name)) then
        local comp_instance = self._components:GetItem (class_name);
        self._components:Rmv (class_name);
        comp_instance:OnRemovedFromHost (self);
    end;
end;

-- 获取组件，以组件类型为参数，不存在则返回nil,
function operation_table.GetComponent (self, comp_class)
    local class_name = Tools.GetClassName (comp_class);
    if (self._components.contains_key (class_name)) then
        return self._components:get_item (class_name);    
    end;
    return nil;
end;

-- 更新
function operation_table.Update (self, current_time, delta_time)
    self._components:BeginIter ();
    for _, _component in self._components:GetIter () do
        _component:Update (current_time, delta_time);
    end;
    self._components:EndIter ();
end;

-- 构造函数
function NewGameEntity (int_id, str_name)
    local instance = _base_class.NewObject ();
    Tools.PrepareInstance (M, instance);
    
    -- 私有成员
    instance._id = int_id;
    instance._name = str_name;

    -- 对象的组件是{class_name}-{class_instance}的映射表，保证每种组件只能添加一次
    instance._components = Map_safe_iter.NewMapSafeIter ();

    -- 每个game_entity都会默认添加一个entity_properties组件
    instance.properties = instance:AddComponent (require ("components.EntityProperties"));

    return instance;
end;

return M;
